/***********************************************************************
 * piezodaemon.h
 * Copyright (C) Muhammad Fauzilkamil Zainuddin <jerungkun@gmail.com>
 * http://coderstalk.blogspot.com
 * 
 * Helper function for Piezometer Daemon
 * 
***********************************************************************/

char logfile[180];		/* log file name variable */
char serialfile[180];	/* serial port variable */
int iflagVerbose=0;		/* verbose flag */
static const char *pid_file = "/var/run/piezometer.pid"; /* pid file */
int wait_flag=TRUE;      /* TRUE while no signal received */
volatile int STOP=FALSE; /* main loop stop flag */
char tmp_data[1024];     /* temporary unprocessed serial data */
int prevmin;			 /* previous minute variable */

/* functions */
void ProcessData(int fd, char *incoming_data);
int ProcessCommand(int fd, char *incoming_line);
void PrintUsage(int argc, char *argv[]);
void appendlog(char *logdata);
void Cleanup(int sig);

/*****************************************************************************
 *  ProcessData - to process raw incoming data and fix the truncat/concat    *
 *  of incoming data                                                         *
 *****************************************************************************/
void ProcessData(int fd, char *incoming_data)
{
	int icheck = 0;
	char delim = '\n';
	char line_data[255];
	char *loc;
	int iloc;
	char tmp_left[1024];
	int ilen = 0;
	int inewlen = 0;
	
	strcat(tmp_data,incoming_data);
	
	while (icheck == 0)
	{
		//sleep(1);
		loc = strchr(tmp_data,delim);	
		ilen = strlen(tmp_data);
		
		//printf("String Length: %d\n", ilen);
		
		if (loc)
		{
			iloc = loc - tmp_data;
			//printf("Location found :%d\n",iloc);
			
			strncpy(line_data,tmp_data,iloc - 1);
			line_data[iloc -1] = '\0';
			
			inewlen = strlen(tmp_data) - (iloc +1);
			memcpy(tmp_left,loc+1,inewlen);
			
			//printf("New Len: %d\n",inewlen);
			//strcpy(tmp_left,loc+1);
			strcpy(tmp_data,tmp_left);
			tmp_data[inewlen] = '\0';
			
			//printf("The Line: '%s'\n", line_data);
			
			if (ProcessCommand(fd,line_data) == 0) {
				printf("The Line: '%s'\n", line_data);
			}
		} else {
			//printf("Character not found!\n\n");
			icheck = 1;
		}
	}
}

/*************************************************************************
 *  ProcessCommand - to process incoming command line from piezometer    *
 *************************************************************************/
int ProcessCommand(int fd, char *incoming_line)
{
	char cmdout[32] = ""; 	/* output command buffer */
	char ssdeg[6] = "";		/* temperature initial */
	char ssbv[6] = "";		/* pressure initial */
	char sfdeg[20] = "";	/* float value for temperature degree */
	char sfbv[20] = "";		/* float value for pressure */
	char logdata[255] = "";	/* log data buffer */
	char syscmd[128] = "";	/* system command buffer */
	int iret = 0;			/* this process return value */
	int ret;				/* return value */
	char mytimestr[30];		/* formatted date & time variable */
	struct tm *local;		/* localtime data structure */
	time_t mytime;			/* date & time variable */
	
	if (strcmp(incoming_line,"Awake") == 0) {
		/* return 1 because we don't wanna see any output */
		iret = 1;
	} else if (strcmp(incoming_line,"M") == 0) {
		/* return 1 because we don't wanna see any output */
		iret = 1;
	} else if (strcmp(incoming_line,"Sleep...") == 0) {
		sleep(1);
		/* the first command will sometime wake the piezometer if it is in sleep mode */
		sprintf(cmdout,"M"); 
		ret = writeport(fd, cmdout);
		sleep(1);
		/* do the second command to ensure the piezometer process it in awake mode */
		sprintf(cmdout,"M");
		ret = writeport(fd, cmdout);

		/* return 1 because we don't wanna see any output */
		iret = 1;
	} else if (strlen(incoming_line) >= 14)	{
		/* scan the incoming line */
		sscanf(incoming_line,"%s %s %s %s",sfbv,ssbv,sfdeg,ssdeg);
		
		/* compare and check to confirm it is the correct line */
		if ((strcmp(ssbv,"B") == 0) && (strcmp(ssdeg,"degC") == 0)) {
			/* check the time */
			mytime = time(NULL);
			local = localtime(&mytime);
			/* we only send data every one minute */
			if (local->tm_min != prevmin)
			{
				/* set the previous minute as current */
				prevmin = local->tm_min;

				/* show the data in log file */
				strftime(mytimestr,sizeof(mytimestr),"%Y/%m/%d %H:%M:%S",local);
				sprintf(logdata,"[%s] Pressure (kPa): %s\t\tTemperature (Celcius): %s",mytimestr,sfbv,sfdeg);
				appendlog(logdata);
				/* print it in verbose mode */
				if (iflagVerbose == 1) {
					printf("%s\n",logdata);
				}
				
				/* send the data to server */
				sprintf(syscmd,"/usr/bin/piezoproc %s %s",sfbv,sfdeg);
				/* trigger the script */
				system(syscmd);
			}
			
			/* return 1 because we don't wanna see any output */
			iret = 1;
		}
	}
	return iret;
}

/**********************************************************************************
 *  Cleanup - to clean up the program variables and memory. Properly close opened
 *  files and port. Remove the process ID file.
 *********************************************************************************/
void Cleanup(int sig) {
	char logdata[28];	/* log data variable */
	char mytimestr[30]; /* formatted date & time variable */
	struct tm *local;	/* localtime data structure */
	time_t mytime;		/* date & time variable */

	/* get current time */
	mytime = time(NULL);
	local = localtime(&mytime);
	/* format the time */
	strftime(mytimestr,sizeof(mytimestr),"%Y/%m/%d %H:%M:%S",local);
	sprintf(logdata,"[%s] Piezometer Terminated...",mytimestr);
	/* log the termination of program */
	appendlog(logdata);
	if (iflagVerbose == 1) {
		printf("%s\n",logdata);
	}
	STOP = TRUE;
	remove(pid_file);
	exit(sig);
}
/***************************************************************************
* signal handler. sets wait_flag to FALSE, to indicate above loop that     *
* characters have been received.                                           *
***************************************************************************/
void signal_handler_IO (int status)
{
	/* trap a signal of incoming data */
	//printf("received SIGIO signal.\n");
	wait_flag = FALSE;
}

/***************************************************************************
 *  PrintUsage - to print how to use this tool
 ***************************************************************************/
void PrintUsage(int argc, char *argv[]) {
    if (argc >=1) {
        printf("Usage: %s -v -h [-L logfilename] [-P serialport]\n", argv[0]);
        printf("  Options:\n");
        printf("      -v\tVerbose\n");
        printf("      -h\tShow this help screen.\n");
        printf("      -L\tWrite output to specified log file.\n");
        printf("      -P\tUse the specified serial port.\n");
        printf("\n");
    }
}

/***************************************************************************
 *  appendlog - to append the data to log file
 ***************************************************************************/
void appendlog(char *logdata){
	FILE *fp;
	
	/* open file for append */
	fp = fopen(logfile,"a+");
	
	if(fp) {
		/* append the log file */
		fprintf(fp,"%s\n",logdata);
	}
	/* close the file */	
	fclose(fp);	
}
